AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")

include('shared.lua')

bombables = {
"prop_physics_multiplayer",
"prop_physics_respawnable",
"prop_physics",
"phys_magnet",
"gmod_spawner", 
"gmod_wheel", 
"gmod_thruster",
"gmod_button",
"sent_keypad",
}
	
function ENT:Initialize()
	self.Entity:SetModel("models/props_c17/oildrum001.mdl")
	self.Entity:SetSkin(1)
	self.BombPanel = ents.Create("prop_dynamic_override")
	self.BombPanel:SetModel("models/weapons/w_c4_planted.mdl")
	self.BombPanel:SetPos(self.Entity:GetPos()+self.Entity:GetAngles():Forward()*10+self.Entity:GetAngles():Up()*25)
	self.BombPanel:SetAngles(Angle(0,90,90))
	self.BombPanel:SetParent(self.Entity)
	self.BombPanel:SetSolid(SOLID_NONE)
	self.BombPanel:SetMoveType(MOVETYPE_NONE)
	
	self.BombPanel2 = ents.Create("prop_dynamic_override")
	self.BombPanel2:SetModel("models/dav0r/tnt/tnt.mdl")
	self.BombPanel2:SetPos(self.Entity:GetPos()+self.Entity:GetAngles():Forward()*-6+self.Entity:GetAngles():Right()*-12+self.Entity:GetAngles():Up()*15)
	self.BombPanel2:SetAngles(Angle(0,45,0))
	self.BombPanel2:SetParent(self.Entity)
	self.BombPanel2:SetSolid(SOLID_NONE)
	self.BombPanel2:SetMoveType(MOVETYPE_NONE)
	
	self.BombPanel3 = ents.Create("prop_dynamic_override")
	self.BombPanel3:SetModel("models/dav0r/tnt/tnt.mdl")
	self.BombPanel3:SetPos(self.Entity:GetPos()+self.Entity:GetAngles():Forward()*-6+self.Entity:GetAngles():Right()*12+self.Entity:GetAngles():Up()*15)
	self.BombPanel3:SetAngles(Angle(0,-45,0))
	self.BombPanel3:SetParent(self.Entity)
	self.BombPanel3:SetSolid(SOLID_NONE)
	self.BombPanel3:SetMoveType(MOVETYPE_NONE)
	
	self.Entity:PhysicsInit(SOLID_VPHYSICS)
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
	self.Entity:SetSolid(SOLID_VPHYSICS)
	
	local phys = self.Entity:GetPhysicsObject()
	if (phys:IsValid()) then
		phys:Wake()
	end
	self.dt.Armed = false
	self.dt.Time = CurTime()
	self.LastUsed = CurTime()
	self.Arming = 50
	self.Disarming = 60
	self.Tick = 0
	util.PrecacheSound("weapons/c4/c4_beep1.wav")
	util.PrecacheSound("weapons/c4/c4_disarm.wav")
	util.PrecacheSound("weapons/c4/c4_explode1.wav")
	util.PrecacheSound("weapons/c4/c4_exp_deb1.wav")
	self.Entity:SetNWBool("armed", false)

end

function ENT:CanRecycle()
	if(self.dt.Armed) then return false else return true end
end

function ENT:Think()
	if (!ValidEntity(self.Owner)) then self:Remove() end
	if (self.dt.Armed==true) then
		if self.LastUsed+3<CurTime() && self.Disarming<60 then
			self.Disarming=self.Disarming+1
			self.Entity:SetColor(self.Disarming*4, self.Disarming*4, self.Disarming*4, 255)
		end
		self.Entity:Beep()
		if (self.dt.Time<CurTime()+5) then
			self.Entity:NextThink(CurTime()+0.125)
		elseif (self.dt.Time<CurTime()+30) then
			self.Entity:NextThink(CurTime()+0.25)
		elseif (self.dt.Time<CurTime()+60) then
			self.Entity:NextThink(CurTime()+0.5)
		else
			self.Entity:NextThink(CurTime()+1)
		end
		return true
	end
end

function ENT:Beep()
	self.Entity:EmitSound(Sound("weapons/c4/c4_beep1.wav"))
end

function ENT:Explode()
	// shield slayer
	for k,v in pairs(player.GetAll()) do
		if v:IsPlayer() && v:GetPos():Distance(self.Entity:GetPos())<1024 && v:GetNWBool("Snipe Shielded")==true then
			v:SetNWBool("Snipe Shielded", false)
			Notify(v, 1, 3, "The force of the Big Bomb shattered your shield!")
		end
	end
	util.BlastDamage(self.Entity, self.Owner, self.Entity:GetPos(), 1536, 2000)
	
	local env = ents.Create("env_physexplosion")
		env:SetKeyValue("magnitude", 9999)
		env.attacker = self.Owner
		env:SetKeyValue("radius", 1536)
		env:SetPos(self.Entity:GetPos())
	env:Spawn()
	env:SetOwner(self.owner)
	env:Fire("explode","",0)
	
	local effectdata = EffectData()
		effectdata:SetStart(Vector(0,0,90))
		effectdata:SetOrigin(self.Entity:GetPos())
		effectdata:SetScale(5)
	util.Effect("effect_explosion_scaleable", effectdata)
	self.Entity:EmitSound(Sound("weapons/c4/c4_explode1.wav"))
	self.Entity:EmitSound(Sound("weapons/c4/c4_exp_deb1.wav"))
	
	local shake = ents.Create("env_shake")
		shake:SetOwner(self.Owner)
		shake:SetPos(self.Entity:GetPos())
		shake:SetKeyValue("amplitude", "3000")
		shake:SetKeyValue("radius", "5000")	
		shake:SetKeyValue("duration", "2.5")
		shake:SetKeyValue("frequency", "255")
		shake:SetKeyValue("spawnflags", "4")
		shake:Spawn()
		shake:Activate()
	shake:Fire("StartShake", "", 0)
	
	local owners,props = self.Entity:FindBreakables()	
	for k, v in pairs(player.GetAll()) do
		local uid = v:UniqueID()
		local propnum = tonumber(owners[uid])
		if (propnum==nil) then propnum = 0 end
		if (tonumber(propnum)>0) then
			Notify(v, 1, 3, "A bigbomb has destroyed " .. tostring(owners[uid]) .. " of your props!")
			v:PrintMessage(HUD_PRINTTALK, "A bigbomb has destroyed " .. tostring(owners[uid]) .. " of your props!")
		end
	end
	
	for k, v in pairs(props) do 
		if(v:GetTheOwner():IsPlayer() && table.HasValue(bombables, v:GetClass())) then
			local entowner = v:GetTheOwner()
			timer.Destroy(tostring(entowner) .. "bigbombed")
			timer.Create(tostring(entowner) .. "bigbombed", 60, 1, function() end)
			v:Remove()
		end
		if(v:GetTheOwner():IsWorld() && table.HasValue(bombables, v:GetClass())) then
			v:Remove()
		end
	end
	
	for i=0, 23, 1 do
		local bomblet = ents.Create("bigbomb_fragment")
		local randpos = Vector(math.random(-5,5), math.random(-5,5), math.random(0,5))
		bomblet.Owner = self.Owner
		bomblet:SetPos(self.Entity:GetPos()+randpos)
		bomblet:Spawn()
		bomblet:Activate()
		bomblet:GetPhysicsObject():SetVelocity(randpos*65+math.random(1,i))
	end 

	self.Entity:Remove()
end

function ENT:Use(activator,caller)
	if self.LastUsed>CurTime() then return end
	
	if (self.dt.Armed) then
		if (self.LastUsed+0.3>CurTime() && self.Disarming==60) then
			self.LastUsed = CurTime()+0.1
		else
			self.LastUsed = CurTime()+0.1
			self.Disarming = self.Disarming-1
			if activator:GetTable().Tooled && self.Tick==1 then
				self.Disarming = self.Disarming-1
			end
			if self.Tick==1 then self.Tick=0 else self.Tick=1 end
			self.Entity:SetColor(self.Disarming*4, self.Disarming*4, self.Disarming*4, 255)
			if (self.Disarming%5==0) then
				self.Entity:Beep()
			end
			if (self.Disarming<=0) then
				Notify(activator,1,3, "Bomb defused!")
				Notify(self.Owner,1,3, "Bomb has been defused.")
				self.Entity:EmitSound(Sound("weapons/c4/c4_disarm.wav"))
				self.Entity:Remove()
			end
		end
	else
		if (self.LastUsed+0.3<CurTime()) then
			self.LastUsed = CurTime()-0.1
			self.Arming = 50
		end
		self.LastUsed = CurTime()+0.1
		self.Arming = self.Arming-1
		if (self.Arming%5==0) then
			self.Entity:Beep()
		end
		if (self.Arming<=0) then
			self.Entity:Armbomb(activator)
		end
	end
end

function ENT:Armbomb(planter)
	if (!self.Entity:CheckPropFaggotry()) then
		self.GravGunPickupAllowed = function () return false end
		self.GravGunPunt = function () return false end
		self:GetPhysicsObject():EnableMotion( false ) 
		self.dt.Armed = true
		self.dt.Time = CurTime()+120
		self.Arming = 50

		local owners,props = self.Entity:FindBreakables()
		for k, v in pairs(player.GetAll()) do
			local uid = v:UniqueID()
			local propnum = tonumber(owners[uid])
			if (propnum==nil) then propnum = 0 end
			if (tonumber(propnum)>0) then
				Notify(ply, 1, 3, "A bigbomb has been planted near " .. tostring(owners[uid]) .. " of your props!")
				ply:PrintMessage(HUD_PRINTTALK, "A bigbomb has been planted near " .. tostring(owners[uid]) .. " of your props!")
			end
		end
		timer.Create(tostring(self.Entity) .. "checkpropshit", 5, 18, self.PropCheck, self)
		timer.Create(tostring(self.Entity) .. "checkblast", 89, 1, self.PropCheck, self)
		timer.Create(tostring(self.Entity) .. "checkblast", 119, 1, self.PropCheck, self)
		timer.Create(tostring(self.Entity) .. "goboom", 120, 1, self.Explode, self)
		Notify(planter, 1, 3, "Bomb has been planted.")
	else
		self.Arming = 50
		Notify(self.Owner, 4, 3, "Get your props away from the bomb for it to be usable.")
		Notify(planter, 4, 3, "bomb owner's props are too close.")
	end
end

function ENT:CheckPropFaggotry()
	local propwallingbitch = false
	for k, v in pairs(ents.FindInSphere(self.Entity:GetPos(), 1536)) do
		if (ValidEntity(v:GetTheOwner()) && v:GetTheOwner():IsPlayer()) then
			local entowner = v:GetTheOwner()
			if self.Owner==entowner then
				propwallingbitch = true
			end
		end
	end
	return propwallingbitch
end

function ENT:PropCheck()
	if (self.Entity:CheckPropFaggotry()) then
		Notify(self.Owner,1,3, "Your props are too close! Bomb has self-defused.")
		self.Entity:EmitSound(Sound("weapons/c4/c4_disarm.wav"))
		self.Entity:Remove()
	end
end

function ENT:FindBreakables()
	local owners = {}
	local props = ents.FindInSphere(self.Entity:GetPos(), 512)
	for k, v in pairs(props) do
		if (v:GetTheOwner():IsPlayer() && table.HasValue(bombables, v:GetClass())) then
			local ownerid = ent:GetTheOwner()
			if (ownerid!=nil && ownerid!=false) then
				if (owners[ownerid]==nil) then
					owners[ownerid]=0
				end
				owners[ownerid] = owners[ownerid]+1
			end
		end
	end
	return owners,props
end

function ENT:UpdateTransmitState() 
	return TRANSMIT_ALWAYS
end

function ENT:OnRemove()
	timer.Destroy(tostring(self.Entity) .. "goboom")
	timer.Destroy(tostring(self.Entity) .. "checkpropshit")
	timer.Destroy(tostring(self.Entity) .. "checkpropshit2")
	timer.Destroy(tostring(self.Entity) .. "checkblast")
end

local function BlockBombing( ply )
	if(timer.IsTimer(tostring(ply) .. "bigbombed")) then return false end
end
hook.Add( "PlayerSpawnProp", "BlockBombing", BlockBombing )